using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEditor.TerrainTools;
using UnityEngine;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using static UnityEngine.EventSystems.EventTrigger;

public class Player : Character
{
    public KeyCodeList keyCode;

    #region Info Of Dead
    public GameObject darkScreen;
    private UI_FadeScreen fadeScreen;
    public GameObject endText;
    public GameObject tryAgainText;
    #endregion

    #region Info Of Player
    //�ƶ�����
    [Header("Move Info")]
    public float moveSpeed;             //�ƶ��ٶ�
    public float defaultMoveSpeed;

    public float jumpForce;             //��Ծ����
    public int maxJumpCount;            //�����Ծ����
    public int currentJumpCount;        //��ǰ��Ծ����
    public float runSpeedMul;           //�����ٶȱ���
    public float defaultJumpForce;

    public float evadeSpeed;            //�����ٶ�
    public float evadeTime;             //����ʱ��

    private float lastTimeLeftPress;
    private float lastTimeRightPress;
    private float maxWaitTime = 0.2f;

    public bool isEvading;              //�Ƿ���������

    [Header("Attack Details")]
    public float[] attackMovement;                  //ÿ�ι���ʱ��λ��
    public float counterAttackDuration = .2f;       //��������ļ��ʱ��

    public bool isBusy;
    #endregion

    public List<String> weaponsInEquipment;
    public string currentWeaponName;
    public ItemData_Weapon currentWeapon;
    public int weaponCount = 0;

    //��ɫ״̬
    #region States
    public PlayerStateMachine stateMachine { get; private set; }        //״̬��

    public PlayerIdleState idleState { get; private set; }              //����״̬
    public PlayerMoveState moveState { get; private set; }              //�ƶ�״̬
    public PlayerRunState runState { get; private set; }                //����״̬
    public PlayerEvadeState evadeState { get; private set; }            //����״̬
    public PlayerJumpState jumpState { get; private set; }              //��Ծ״̬
    public PlayerAirState airState { get; private set; }                //����״̬
    public PlayerPriAtkState attackState { get; private set; }          //����״̬
    public PlayerSpecialAtkState specialAtkState { get; private set; }
    public PlayerDeadState deadState { get; private set; }
    #endregion 

    protected override void Awake()
    {
        base.Awake();

        stateMachine = new PlayerStateMachine();

        #region InstantiationState
        idleState = new PlayerIdleState(this, stateMachine, "Idle");
        moveState = new PlayerMoveState(this, stateMachine, "Move");
        runState = new PlayerRunState(this, stateMachine, "Run");
        evadeState = new PlayerEvadeState(this, stateMachine, "Evade");
        jumpState = new PlayerJumpState(this, stateMachine, "Jump");
        airState = new PlayerAirState(this, stateMachine, "Jump");
        attackState = new PlayerPriAtkState(this, stateMachine, "Attack");
        specialAtkState = new PlayerSpecialAtkState(this, stateMachine, "SpecialAtk");
        deadState = new PlayerDeadState(this, stateMachine, "Dead");
        #endregion
    }

    protected override void Start()
    {
        base.Start();

        stateMachine.Initialize(idleState);     //���״̬��ʼ��Ϊ idle ״̬

        fadeScreen = darkScreen.GetComponent<UI_FadeScreen>();

        defaultMoveSpeed = moveSpeed;
        defaultJumpForce = jumpForce;

        lastTimeLeftPress = lastTimeRightPress = -maxWaitTime;

        weaponsInEquipment = new List<string>();
    }

    protected override void Update()
    {
        base.Update();

        stateMachine.currentState.Update();         //ʵʱ����״̬����ǰ״̬

        if(Input.GetKeyDown(KeyCode.Q))
            SwitchCurrentWeapon();

        if (Input.GetKeyDown(KeyCode.LeftShift))
            stateMachine.ChangeState(evadeState);

        RunCheck();
    }

    #region Weapon Function

    private void SwitchCurrentWeapon()          //�л���ǰ����
    {
        weaponCount += 1;
        if(weaponCount == weaponsInEquipment.Count) weaponCount = 0;
        currentWeaponName = weaponsInEquipment[weaponCount];
        currentWeapon = Inventory.instance.weaponInEquipment[weaponCount];
    }

    public void GetWeaponFromEquipment()            //��װ������ȡ����
    {
        for(int i = 0; i < Inventory.instance.weaponInEquipment.Count; i++) 
        {
            ItemData_Weapon weapon = Inventory.instance.weaponInEquipment[i];
            weaponsInEquipment.Add(weapon.name);
        }

        for(int i = 0; i < weaponsInEquipment.Count; i++) 
        {
            if(weaponsInEquipment[i] != null)
            {
                currentWeaponName = weaponsInEquipment[i];
                weaponCount = i;
                currentWeapon = Inventory.instance.weaponInEquipment[weaponCount];
                return;
            }
        }
    }
    #endregion

    private void RunCheck()     //����״̬���
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            if (Time.time - lastTimeLeftPress < maxWaitTime)
            {
                stateMachine.ChangeState(runState);
            }
            lastTimeLeftPress = Time.time;
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            if (Time.time - lastTimeRightPress < maxWaitTime)
            {
                stateMachine.ChangeState(runState);
            }
            lastTimeRightPress = Time.time;
        }
    }

    

    public IEnumerator BusyFor(float _seconds)    //�ж�����Ƿ���æµ�еĺ���  
    {
        isBusy = true;          //���� isBusy

        yield return new WaitForSeconds(_seconds);

        isBusy = false;
    }

    public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();       //�������ʱ���ض����������ź�

    #region Dead Function

    public override void Die()
    {
        base.Die();

        stateMachine.ChangeState(deadState);
    }

    public void SwitchOnEndScreen()
    {
        fadeScreen.FadeOut();

        StartCoroutine(EndScreenCorutione());
    }

    IEnumerator EndScreenCorutione()
    {
        yield return new WaitForSeconds(1);
        endText.SetActive(true);

        yield return new WaitForSeconds(1);
        tryAgainText.SetActive(true);
    }

    public void RestartGameButton() => GameManager.instance.RestartSceene();
    #endregion
}
